package com.jinxinol.core.util;

import java.lang.reflect.Array;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Collection;
import java.util.Date;
import java.util.Map;

/**
 * <p>用于处理一般对象的若干静态方法。</p>
 * 
 */
public abstract class ObjectUtils {

	/**
	 * 判断两个对象是否相同（equals）。<br>
	 * 如果两个对象都是null，则返回true，如果只有一个对象是null，则返回false。
	 * 
	 * @param o1 要比较的第一个对象。
	 * @param o2 要比较的第二个对象。
	 * @return boolean 两个对象是否相同。
	 */
	public static boolean nullSafeEquals(Object o1, Object o2) {
		return (o1 == o2 || (o1 != null && o1.equals(o2)));
	}

	/**
	 * 返回对象hash code的16进制字符串。
	 * 
	 * @param obj 输入对象。
	 * @return String 对象hash code的16进制字符串。
	 */
	public static String getIdentityHexString(Object obj) {
		return Integer.toHexString(System.identityHashCode(obj));
	}

	/**
	 * 判断一个对象数组是否为空。<br>
	 * 数组对象为null或者长度为0，则返回true。
	 * 
	 * @param array 需要检查的数组对象。
	 * @return boolean 是否为空。
	 */
	public static boolean isEmpty(Object[] array) {
		return (array == null || array.length == 0);
	}
	
	/**
	 * 判断一个集合数组是否为空。<br>
	 * 集合对象为null或者长度为0，则返回true。
	 * 
	 * @param coll 需要检查的集合对象。
	 * @return boolean 是否为空。
	 */
	public static boolean isEmpty(Collection<? extends Object> coll) {
		return (coll == null || coll.size() == 0);
	}
	
	/**
	 * 判断一个Map数组是否为空。<br>
	 * Map对象为null或者长度为0，则返回true。
	 * 
	 * @param map 需要检查的Map对象。
	 * @return boolean 是否为空。
	 */
	public static boolean isEmpty(Map<? extends Object, ? extends Object> map) {
		return (map == null || map.size() == 0);
	}

	/**
	 * 将一个对象加入到已经存在的对象数组中（尾部）。<br>
	 * 如果对象数组为null，则创建一个新的对象数组。
	 * 
	 * @param array 已经存在的数组 (可以为null)。
	 * @param obj 需要加入数组的对象。
	 * @return Object[] 新的数组(一定不是null)。
	 */
	@SuppressWarnings("rawtypes")
	public static Object[] addObjectToArray(Object[] array, Object obj) {
		Class compType = Object.class;
		if (array != null) {
			compType = array.getClass().getComponentType();
		}
		else if (obj != null) {
			compType = obj.getClass();
		}
		int newArrLength = (array != null ? array.length + 1 : 1);
		Object[] newArr = (Object[]) Array.newInstance(compType, newArrLength);
		if (array != null) {
			System.arraycopy(array, 0, newArr, 0, array.length);
		}
		newArr[array.length] = obj;
		return newArr;
	}

	/**
	 * 返回某个值对象的元素个数。<br>
	 * 如果对象类型为集合对象（Collection、Map）时，则返回集合中元素的个数，对象为其他类型时返回1。<br>
	 * 如果表中不存在该对象，则放回0。
	 * @param value 值对象。
	 * @return 对象的元素个数。
	 */
	
	@SuppressWarnings("rawtypes")
	public static int getObjectSize(Object value) {
		// 如果值对象不存在，则返回0
		if (value == null) {
			return 0;
		}
		// 如果值对象的类型为Collection，则返回size
		else if (value instanceof Collection) {
			return ((Collection)value).size();
		}
		// 如果值对象的类型为Map，则返回size
		else if (value instanceof Map) {
			return ((Map)value).size();
		}
		// 否则，返回1
		else {
			return 1;
		}
	}
	
	/**
	 * <p>将对象转换成boolean类型。</p>
	 *
	 * @param source 原始对象。
	 * @return boolean boolean类型值。
	 */
	public static boolean parseBoolean(Object source) {
		if (source != null) {
			String str = source.toString();
			return ( StringUtils.equalsWithIgnoreCase(str, "true") || source.equals("1") );
		}
		
		return false;
	}
	
	/**
	 * <p>将对象转换成byte类型。</p>
	 *
	 * @param source 原始对象。
	 * @return byte byte类型值。
	 */
	public static byte parseByte(Object source) {
		return ObjectUtils.parseByte(source, (byte)0);
	}

	/**
	 * <p>将对象转换成byte类型。</p>
	 *
	 * @param source 原始对象。
	 * @param defaultValue 缺省值。
	 * @return byte byte类型值。
	 */
	public static byte parseByte(Object source, byte defaultValue) {
		try {
			return Byte.parseByte(source.toString());
		} catch (Exception e) {
			return defaultValue;
		}
	}

	/**
	 * <p>将对象转换成int类型。</p>
	 *
	 * @param source 原始对象。
	 * @return int int类型值。
	 */
	public static int parseInt(Object source) {
		return ObjectUtils.parseInt(source, 0);
	}

	/**
	 * <p>将对象转换成int类型。</p>
	 *
	 * @param source 原始对象。
	 * @param defaultValue 缺省值。
	 * @return int int类型值。
	 */
	public static int parseInt(Object source, int defaultValue) {
		try {
			return Integer.parseInt(source.toString());
		} catch (Exception e) {
			return defaultValue;
		}
	}

	/**
	 * <p>将对象转换成Integer类型。</p>
	 *
	 * @param source 原始对象。
	 * @return Integer Integer类型值。
	 */
	public static Integer parseInteger(Object source) {
		try {
			return Integer.valueOf(source.toString());
		} catch (Exception e) {
			return null;
		}
	}

	/**
	 * <p>将对象转换成Long类型。</p>
	 *
	 * @param source 原始对象。
	 * @return Long Long类型值。
	 */
	public static Long parseLong(Object source) {
		try {
			return Long.valueOf(source.toString());
		} catch (Exception e) {
			return null;
		}
	}

	/**
	 * <p>将对象转换成Float类型。</p>
	 *
	 * @param source 原始对象。
	 * @return Float Float类型值。
	 */
	public static Float parseFloat(Object source) {
		try {
			return Float.valueOf(source.toString());
		} catch (Exception e) {
			return null;
		}
	}

	/**
	 * <p>将对象转换成Double类型。</p>
	 *
	 * @param source 原始对象。
	 * @return Double Double类型值。
	 */
	public static Double parseDouble(Object source) {
		try {
			return Double.valueOf(source.toString());
		} catch (Exception e) {
			return null;
		}
	}
	
	/**
	 * <p>将对象转换成Date类型。</p>
	 *
	 * @param source 原始对象。
	 * @param DateFormat 格式对象。
	 * @return Date Date类型值。
	 */
	public static Date parseDate(Object source, DateFormat dataFormat) {
		try {
			return dataFormat.parse(source.toString());
		} catch (Exception e) {
			return null;
		}
	}
	
	/**
	 * <p>将对象转换成Date类型。</p>
	 *
	 * @param source 原始对象。
	 * @param DateFormat 格式字符串。
	 * @return Date Date类型值。
	 */
	public static Date parseDate(Object source, String dateFormat) {
		if (!StringUtils.hasLength(dateFormat) ) {
			dateFormat = "yyyy-MM-dd HH:mm:ss";
		}
		return ObjectUtils.parseDate(source, new SimpleDateFormat(dateFormat));
	}

}
